function A405()
format long;

% ======== 加载数据（生成三个相近组织类型） ========
[X, y] = generateUTdata();
y = categorical(y);
y = reordercats(y, {'软组织', '肌肉', '硬组织外膜'});  % 使用中文类别名称

classNames = categories(y);

% ======== 图1：原始数据散点图（弹性模量 vs 波阻抗） ========
subplot(2,2,1)
gscatter(X(:,2), X(:,3), y, 'rgy', '.');
title('{\bf 软组织类型原始散点图}');
xlabel('弹性模量 (GPa)');
ylabel('波阻抗 (MRayl)');
legend('软组织', '肌肉组织', '硬组织外膜', 'Location', 'best');
grid on;

% ======== 图2：多类 SVM 分类区域图 ========
SVMModels = cell(numel(classNames), 1);
rng(1);
for j = 1:numel(classNames)
    idx = y == classNames{j};
    SVMModels{j} = fitcsvm(X(:,[2,3]), idx, ...
        'ClassNames', [false true], ...
        'KernelFunction', 'rbf', ...
        'Standardize', true, ...
        'BoxConstraint', 1);
end

% 网格生成
d = 0.001;
[x1Grid, x2Grid] = meshgrid(min(X(:,2)):d:max(X(:,2)), min(X(:,3)):d:max(X(:,3)));
xGrid = [x1Grid(:), x2Grid(:)];
N = size(xGrid,1);
Scores = zeros(N, numel(classNames));
for j = 1:numel(classNames)
    [~, score] = predict(SVMModels{j}, xGrid);
    Scores(:,j) = score(:,2);  % 正类得分
end
[~, maxScore] = max(Scores, [], 2);

% 区域颜色接近 Iris 示例图风格
regionColors = [
    0.4 0.7 0.7;   % soft_tissue region - 青绿色
    0.6 0.4 0.7;   % muscle region - 紫色
    0.7 0.6 0.3];  % periosteum region - 土黄

subplot(2,2,2)
gscatter(xGrid(:,1), xGrid(:,2), maxScore, regionColors, '.', 1);
hold on
gscatter(X(:,2), X(:,3), y,'rgy', '.');
title('{\bf 多类 SVM 分类区域图}');
xlabel('弹性模量 (GPa)');
ylabel('波阻抗 (MRayl)');
xlim([-0.123, 0.149]);
ylim([1.4 2.2]);
legend('软组织区域','肌肉区域','硬组织区域', '软组织','肌肉组织','硬组织外膜','Location','best');
grid on;
hold off;

% ======== 图3：三分类 SVM 混淆矩阵（所有组织） ========

% 数据分割
cv_all = cvpartition(y, 'HoldOut', 0.3);
XTrain_all = X(training(cv_all), [2,3]);
YTrain_all = y(training(cv_all));
XTest_all = X(test(cv_all), [2,3]);
YTest_all = y(test(cv_all));

% 多类 SVM 训练（使用 one-vs-all 模式）
template = templateSVM('Standardize', true, 'KernelFunction', 'rbf');
SVMModel_all = fitcecoc(XTrain_all, YTrain_all, 'Learners', template);

% 预测
YPred_all = predict(SVMModel_all, XTest_all);

% --- 强制保证类别顺序 ---
% 将预测和真实标签转换为有序分类变量
classOrder = {'软组织', '肌肉', '硬组织外膜'};
YTest_all = categorical(YTest_all, classOrder, 'Ordinal', true);
YPred_all = categorical(YPred_all, classOrder, 'Ordinal', true);

% 生成混淆矩阵数据
cmMatrix = confusionmat(YTest_all, YPred_all);

% 绘制混淆矩阵热图
subplot(2,2,3)
% % 生成真实混淆矩阵
% cmMatrix = confusionmat(YTest_all, YPred_all);

% 绘制基础图像（白色背景）
imagesc(zeros(size(cmMatrix)));  % 所有值为0，统一底色
colormap([1 1 1]);  % 白色背景
axis equal;
hold on;

% 自定义颜色
customColors = {
    [1 0 0], 1, 1;  % 红色 -> (1,1)
    [0 1 0], 2, 2;  % 绿色 -> (2,2)
    [1 1 0], 3, 3;  % 黄色 -> (3,3)
};

% 绘制彩色方块
for k = 1:size(customColors,1)
    color = customColors{k,1};
    row = customColors{k,2};
    col = customColors{k,3};
    x = [col-0.5, col+0.5, col+0.5, col-0.5];
    y = [row-0.5, row-0.5, row+0.5, row+0.5];
    patch(x, y, color, 'EdgeColor', 'none');
end

% 添加数字标签
for i = 1:size(cmMatrix, 1)
    for j = 1:size(cmMatrix, 2)
        text(j, i, num2str(cmMatrix(i,j)), ...
            'HorizontalAlignment', 'center', ...
            'VerticalAlignment', 'middle', ...
            'Color', 'k', ...
            'FontSize', 12, ...
            'FontWeight', 'bold');
    end
end

% 设置坐标轴
set(gca, 'XTick', 1:3, 'XTickLabel', {'软组织','肌肉','硬组织外膜'});
set(gca, 'YTick', 1:3, 'YTickLabel', {'软组织','肌肉','硬组织外膜'});
xlabel('预测类别');
ylabel('真实类别');
xlim([0.5 3.5]);
ylim([0.5 3.5]);

title('三分类 SVM 混淆矩阵');
grid off;
box on;
hold off;


% ======== 图4：每类预测的准确率与错误率（使用 bar 图） ========
% 获取混淆矩阵
cmMatrix = confusionmat(YTest_all, YPred_all);

% 计算每个类别的准确率
accuracy_per_class = diag(cmMatrix) ./ sum(cmMatrix, 2) * 100;

% 计算错误率
error_per_class = 100 - accuracy_per_class;

% 创建一个二维矩阵显示准确率和错误率
accuracy_matrix = [accuracy_per_class'; error_per_class'];

% 创建 bar 图
subplot(2,2,4);

%% 创建 bar 图
subplot(2,2,4);

% 绘制准确率和错误率的堆积条形图，并获取句柄
hBar = bar(accuracy_matrix', 'stacked');

% 设置颜色
hBar(1).FaceColor = [0.2 0.7 0.2];  % 准确率颜色：绿色
hBar(2).FaceColor = [0.7 0.7 0.7];  % 错误率颜色：灰色

% 设置轴标签
set(gca, 'XTick', 1:numel(classNames), 'XTickLabel', classNames);
set(gca, 'YTick', 0:20:100);
legend({'准确率', '错误率'}, 'Location', 'Best');
xlabel('类        别');
ylabel('百分比 (%)');

% 添加文本标签
for i = 1:numel(classNames)
    for j = 1:2
        y_offset = sum(accuracy_matrix(1:j-1, i));
        text(i, y_offset + accuracy_matrix(j, i)/2, ...
            sprintf('%.1f%%', accuracy_matrix(j, i)), ...
            'HorizontalAlignment', 'center', ...
            'VerticalAlignment', 'middle', ...
            'Color', 'k', 'FontSize', 12);
    end
end

title('每类预测的准确率与错误率');


end


function [utData, utLabels] = generateUTdata()
    numSamplesPerClass = 150;
    utData = zeros(numSamplesPerClass * 3, 4);
    utLabels = cell(numSamplesPerClass * 3, 1);

    % 类别1：软组织（软组织数据被优化，增加了与其他类别的区分度）
    utData(1:150,:) = [ ...
        normrnd(0.65, 0.05, [150,1]), ...       % 衰减系数 (dB/cm)
        normrnd(0.008, 0.0002, [150,1]), ...   % 弹性模量 (GPa) 更小的标准差减少与其他类别的重叠
        normrnd(1.85, 0.05, [150,1]), ...       % 波阻抗 (MRayl)
        normrnd(0.95, 0.03, [150,1])];         % 密度 (g/cm³)
    utLabels(1:150) = repmat({'软组织'}, 150, 1);

    % 类别2：肌肉组织
    utData(151:300,:) = [ ...
        normrnd(0.8, 0.1, [150,1]), ...
        normrnd(0.006, 0.001, [150,1]), ...
        normrnd(1.6, 0.1, [150,1]), ...
        normrnd(1.07, 0.03, [150,1])];
    utLabels(151:300) = repmat({'肌肉'}, 150, 1);

    % 类别3：硬组织外膜
    utData(301:450,:) = [ ...
        normrnd(1.0, 0.1, [150,1]), ...
        normrnd(0.015, 0.002, [150,1]), ...
        normrnd(2.0, 0.1, [150,1]), ...
        normrnd(1.15, 0.05, [150,1])];
    utLabels(301:450) = repmat({'硬组织外膜'}, 150, 1);

    % 添加轻微测量噪声
    utData = utData + 0.05 * randn(size(utData));
end

